package com.heimali.happyreader.services;

import java.util.ArrayList;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;

import com.heimali.happyreader.ArticleListActivity;
import com.heimali.happyreader.R;
import com.heimali.happyreader.Statics;
import com.heimali.happyreader.config.Constants;
import com.heimali.happyreader.config.PersonalConfig;
import com.heimali.happyreader.db.dao.ArticleDao;
import com.heimali.happyreader.db.dao.ListDao;
import com.heimali.happyreader.model.Article;
import com.heimali.happyreader.model.Intro;
import com.heimali.happyreader.utils.HttpUtils;
import com.heimali.happyreader.utils.LogicUtils;
import com.heimali.happyreader.wraper.ArticleListWraper;
import com.heimali.happyreader.wraper.ArticleWraper;
import com.heimali.happyreader.wraper.BaseWraper;

public class DownloadService extends Service {
	/**
	 * 1、同步recent list 读取当前DB list最大值 从网络获取最新20条 list，
	 * 其最小id与上次记录的最大值比较，判断出是否同步完成recent数据 没同步完，取list的最小id向前取，直到同步完成
	 * 
	 * 2、同步early list 检查sp中记录的同步完成的最小值，如有记录代表已同步过先前数据，没有则开始同步读取DB list最小id向前取，
	 * 同步更早数据如果反回数据条数不足20条（1页），则同步完成，sp记录最小id 
	 * 
	 * 3、同步文件内容
	 */
	public final String TAG = "DownloadService";

	private final int SYNC_EARLY_LIST_SUCCESS = 100;
	private final int SYNC_EARLY_LIST_FAIL = 101;
	private final int SYNC_EARLY_LIST_COMPLETE = 102;

	private final int SYNC_RECENT_LIST_SUCCESS = 103;
	private final int SYNC_RECENT_LIST_FAIL = 104;
	private final int SYNC_RECENT_LIST_COMPLETE = 105;

	private final int SYNC_ARTICLE_SUCCESS = 106;
	private final int SYNC_ARTICLE_FAIL = 107;
	private final int SYNC_ARTICLE_COMPLETE = 108;

	private int minListID = -1;
	private int maxListID = -1;
	private ArrayList<Integer> unSyncArticleIDs = new ArrayList<Integer>();

	private NotificationManager notificationManager;
	private Notification notification;

	public Handler handler = new Handler() {
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case SYNC_EARLY_LIST_SUCCESS:
				_syncEaryList(msg.arg1);
				break;
			case SYNC_EARLY_LIST_FAIL:
				syncFail();
				break;
			case SYNC_EARLY_LIST_COMPLETE:
				PersonalConfig.getInstance().setConfig(Constants.PERSONAL_CONFIG_EARLY_DOWNLOAD_COMPLETE, true);
				syncArticle();
				break;
			case SYNC_RECENT_LIST_SUCCESS:
				_syncRecentList(msg.arg1);
				break;
			case SYNC_RECENT_LIST_FAIL:
				syncFail();
				break;
			case SYNC_RECENT_LIST_COMPLETE:
				syncEaryList();
				break;
			case SYNC_ARTICLE_SUCCESS:
			case SYNC_ARTICLE_FAIL:
				if (unSyncArticleIDs.isEmpty()) {
					_syncArticle();
				} else {
					int articleID = unSyncArticleIDs.remove(0);
					_downloadArticle(articleID);
				}
				break;
			case SYNC_ARTICLE_COMPLETE:
				syncCompelete();
				break;
			}
		}
	};

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	public void onCreate() {
		super.onCreate();
		showNotification(Constants.NOTIFY_SYNC_LIST);
		syncRecentList();
	}

	public void onStart(Intent intent, int startId) {
		super.onStart(intent, startId);
	}

	public void onDestroy() {
		super.onDestroy();
	}

	public void syncFail() {
		showNotification(Constants.NOTIFY_SYNC_FAIL);
		stopSelf();
	}

	public void syncCompelete() {
		PersonalConfig.getInstance().setConfig(Constants.PERSONAL_CONFIG_ARTICLE_COMPLETE, true);
		showNotification(Constants.NOTIFY_SYNC_COMPLETE);
		cancelNotification();
		stopSelf();
	}

	public void syncRecentList() {
		if (maxListID == -1) {
			maxListID = new ListDao().queryMaxArticleID();
		}
		_syncRecentList(maxListID);
	}

	private void _syncRecentList(final int maxID) {
		String query = HttpUtils.buildQuery(new String[] { "id", Statics.getUid() },
				new String[] { "last_id", String.valueOf(maxID) }, new String[] { "token", Statics.getToken() });

		new ArticleListWraper(HttpUtils.buildURI(Constants.listUpdateRecentIntfPath, query), new BaseWraper.Callback() {

			@SuppressWarnings("unchecked")
			public void onSuccess(Object result) {
				final ArrayList<Intro> list = (ArrayList<Intro>) result;
				if (list.isEmpty()) {
					handler.sendEmptyMessage(SYNC_RECENT_LIST_COMPLETE);
					return;
				}

				new Thread(new Runnable() {
					public void run() {
						new ListDao().insertNewRecord(list);
						if (list.size() < Constants.LIST_PAGE_SIZE) {
							handler.sendEmptyMessage(SYNC_RECENT_LIST_COMPLETE);
						} else {
							int newMaxID = LogicUtils.getListMaxID(list, maxID);
							handler.obtainMessage(SYNC_RECENT_LIST_SUCCESS, newMaxID, 0).sendToTarget();
						}
					}
				}).start();
			}

			public void onFail(int errno, String errmsg) {
				handler.sendEmptyMessage(SYNC_RECENT_LIST_FAIL);
			}

		}).execute();
	}

	public void syncEaryList() {
		if (PersonalConfig.getInstance().getConfig(Constants.PERSONAL_CONFIG_EARLY_DOWNLOAD_COMPLETE, false)) {
			handler.sendEmptyMessage(SYNC_EARLY_LIST_COMPLETE);
			return;
		}

		if (minListID == -1) {
			minListID = new ListDao().queryMinArticleID();
		}

		_syncEaryList(minListID);
	}

	private void _syncEaryList(int minID) {
		String query = HttpUtils.buildQuery(new String[] { "id", Statics.getUid() },
				new String[] { "last_id", String.valueOf(minID) }, new String[] { "token", Statics.getToken() });

		new ArticleListWraper(HttpUtils.buildURI(Constants.listUpdateEarlyIntfPath, query), new BaseWraper.Callback() {

			@SuppressWarnings("unchecked")
			public void onSuccess(Object result) {
				final ArrayList<Intro> list = (ArrayList<Intro>) result;

				if (list.isEmpty()) {
					handler.sendEmptyMessage(SYNC_EARLY_LIST_COMPLETE);
					return;
				}

				new Thread(new Runnable() {
					public void run() {
						new ListDao().insertNewRecord(list);
						if (list.size() < Constants.LIST_PAGE_SIZE) {
							handler.sendEmptyMessage(SYNC_EARLY_LIST_COMPLETE);
						} else {
							int minID = new ListDao().queryMinArticleID();
							handler.obtainMessage(SYNC_EARLY_LIST_SUCCESS, minID, 0).sendToTarget();
						}
					}
				}).start();
			}

			public void onFail(int errno, String errmsg) {
				handler.sendEmptyMessage(SYNC_EARLY_LIST_FAIL);
			}

		}).execute();
	}

	public void syncArticle() {
		showNotification(Constants.NOTIFY_SYNC_ARTICLE);
		if (PersonalConfig.getInstance().getConfig(Constants.PERSONAL_CONFIG_ARTICLE_COMPLETE, false)) {
			handler.sendEmptyMessage(SYNC_ARTICLE_COMPLETE);
			return;
		}

		_syncArticle();
	}

	private void _syncArticle() {

		unSyncArticleIDs = (ArrayList<Integer>) new ListDao().queryUnSyncArticleIDs(Constants.LIST_PAGE_SIZE);
		// SystemUtils.Log(TAG, "_syncArticle", unSyncArticleIDs.isEmpty(),
		// unSyncArticleIDs.size());
		if (unSyncArticleIDs.isEmpty()) {
			handler.sendEmptyMessage(SYNC_ARTICLE_COMPLETE);
			return;
		}

		int articleID = unSyncArticleIDs.remove(0);
		_downloadArticle(articleID);
	}

	private void _downloadArticle(int articleID) {

		new ArticleWraper(articleID, new BaseWraper.Callback() {
			public void onSuccess(Object result) {
				final Article article = (Article) result;
				new Thread(new Runnable() {
					public void run() {
						int count = new ArticleDao().insert(article);
						if (count > 0) {
							new ListDao().updateIsDownload(article.id);
						}
						handler.sendEmptyMessage(SYNC_ARTICLE_SUCCESS);
					}
				}).start();
			}

			public void onFail(int errno, String errmsg) {
				handler.sendEmptyMessage(SYNC_ARTICLE_FAIL);
			}
		}).execute();
	}

	public void showNotification(int status) {

		notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
		notification = new Notification(android.R.drawable.stat_sys_download, getString(R.string.app_name),
				System.currentTimeMillis());
		notification.flags = Notification.FLAG_AUTO_CANCEL;

		Intent intent = new Intent(this, ArticleListActivity.class);
		intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);

		String title = getString(R.string.app_name) + " - " + getString(R.string.notify_title_offline_download), content = "";
		switch (status) {
		case Constants.NOTIFY_SYNC_LIST:
			content = getString(R.string.notify_content_sync_list);
			break;
		case Constants.NOTIFY_SYNC_ARTICLE:
			content = getString(R.string.notify_content_sync_article);
			break;
		case Constants.NOTIFY_SYNC_FAIL:
			content = getString(R.string.notify_content_sync_fail);
			break;
		case Constants.NOTIFY_SYNC_COMPLETE:
			content = getString(R.string.notify_content_sync_complete);
			break;
		}

		PendingIntent contentIntent = PendingIntent.getActivity(this, R.string.app_name, intent,
				PendingIntent.FLAG_UPDATE_CURRENT);
		notification.setLatestEventInfo(this, title, content, contentIntent);
		notificationManager.notify(R.string.app_name, notification);
	}

	public void cancelNotification() {
		handler.postDelayed(new Runnable() {
			public void run() {
				notificationManager.cancel(R.string.app_name);
			}
		}, 2000);

	}
}
